//
// Created by LiuYou on 2021/10/27.
//

#include <iostream>
#include <cstring>


static const int BUF_SIZE = 100;
static FILE* fp;


int getLine(char** lineBuf, int* lineSize, FILE* filePtr) {
    if (*lineBuf == nullptr) {
        *lineSize = 100;
        *lineBuf = static_cast<char*>(malloc( *lineSize ));
        if (*lineBuf == nullptr) {
            return -1;
        }
    }

    // 该读取一行中的字符的个数。
    int lineChars{};
    while (true) {

        int readChar = fgetc( filePtr );
        // 读取完整的一行。
        if (readChar == '\n') {
            (*lineBuf)[lineChars] = (char) readChar;
            ++lineChars;
            break;
        }
        // 读到文件末尾一行。
        /*
         * todo 笔记: 这里要注意, 如果文件的最后一行不是单独的一行, 这样就错了。下一个版本 9 中改进。
         */
        if (readChar == EOF) {
            return -1;
        }

        (*lineBuf)[lineChars] = (char) readChar;
        ++lineChars;

        if (lineChars > *lineSize) {
            *lineBuf = static_cast<char*>(realloc( *lineBuf, 2 * (*lineSize)));
            if (*lineBuf == nullptr) {
                return -1;
            }
            *lineSize = (*lineSize) * 2;
        }


    }

    return lineChars;
}

int getLineFree(char* lineBuf) {
    free( lineBuf );
    return 0;
}


/*
 * 在 7 的基础上改进。
 */
int main(int argc, char** argv) {
    if (argc < 2) {
        fprintf( stderr, "用法: %s filename\n", argv[0] );
        return 1;
    }

    fp = fopen( argv[1], "r" );
    if (fp == nullptr) {
        perror( "fopen()" );
        return 1;
    }
    atexit( []() -> void {
        fclose( fp );
    } );


    int lineLength{BUF_SIZE};
    char* lineBuffer = static_cast<char*>(malloc( BUF_SIZE ));
    int lineNum{};

    while (true) {
        ssize_t readBytes = getLine( &lineBuffer, &lineLength, fp );
        if (readBytes < 0) {
            break;
        }
        ++lineNum;

        printf( "%d 行的字节数为: %zd。 ", lineNum, readBytes );

        printf( "%d\n", lineLength );
    }


    getLineFree( lineBuffer );


    return 0;
}